/* * Copyright 2001-2005 Stephen Colebourne * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.joda.time.chrono.gj; import org.joda.time.DateTimeField; /** * A reference Julian chronology implementation, intended for testing purposes * only. Correctness is favored over performance. The key functions for date * calculations are based on ones provided in "Calendrical Calculations", ISBN * 0-521-77752-6. * * @author Brian S O'Neill */ public final class TestJulianChronology extends TestGJChronology { private static final long JULIAN_EPOCH; static { // Constant as defined in book. JULIAN_EPOCH = new TestGregorianChronology().fixedFromGJ(0, 12, 30); } /** * Constructs with an epoch of 1969-12-19. */ public TestJulianChronology() { super(1969, 12, 19); } public TestJulianChronology(int epochYear, int epochMonth, int epochDay) { super(epochYear, epochMonth, epochDay); } public DateTimeField dayOfMonth() { return new TestJulianDayOfMonthField(this); } public DateTimeField weekyear() { return new TestJulianWeekyearField(this); } public DateTimeField monthOfYear() { return new TestJulianMonthOfYearField(this); } public DateTimeField year() { return new TestJulianYearField(this); } public String toString() { return "TestJulianChronology"; } long millisPerYear() { return (long)(365.25 * MILLIS_PER_DAY); } long millisPerMonth() { return (long)(365.25 * MILLIS_PER_DAY / 12); } boolean isLeapYear(int year) { if (year == 0) { throw new IllegalArgumentException("Illegal year: " + year); } return mod(year, 4) == (year > 0 ? 0 : 3); } /** * @return days from 0001-01-01 */ long fixedFromGJ(int year, int monthOfYear, int dayOfMonth) { if (year == 0) { throw new IllegalArgumentException("Illegal year: " + year); } int y = (year < 0) ? year + 1 : year; long y_m1 = y - 1; long f = JULIAN_EPOCH - 1 + 365 * y_m1 + div(y_m1, 4) + div(367 * monthOfYear - 362, 12) + dayOfMonth; if (monthOfYear > 2) { f += isLeapYear(year) ? -1 : -2; } return f; } /** * @param date days from 0001-01-01 * @return gj year */ int gjYearFromFixed(long date) { return gjFromFixed(date)[0]; } /** * @param date days from 0001-01-01 * @return gj year, monthOfYear, dayOfMonth */ int[] gjFromFixed(long date) { long approx = div(4 * (date - JULIAN_EPOCH) + 1464, 1461); long year = (approx <= 0) ? approx - 1 : approx; int year_i = (int)year; if (year_i != year) { throw new RuntimeException("year cannot be cast to an int: " + year); } long priorDays = date - fixedFromGJ(year_i, 1, 1); long correction; if (date < fixedFromGJ(year_i, 3, 1)) { correction = 0; } else if (isLeapYear(year_i)) { correction = 1; } else { correction = 2; } int monthOfYear = (int)div(12 * (priorDays + correction) + 373, 367); int day = (int)(date - fixedFromGJ(year_i, monthOfYear, 1) + 1); return new int[]{year_i, monthOfYear, day}; } long fixedFromISO(int weekyear, int weekOfWeekyear, int dayOfWeek) { if (weekyear == 0) { throw new IllegalArgumentException("Illegal weekyear: " + weekyear); } if (weekyear == 1) { weekyear = -1; } else { weekyear--; } return nthWeekday(weekOfWeekyear, 0, weekyear, 12, 28) + dayOfWeek; } /** * @param date days from 0001-01-01 * @return iso weekyear, weekOfWeekyear, dayOfWeek (1=Monday to 7) */ int[] isoFromFixed(long date) { int weekyear = gjYearFromFixed(date - 3); int nextWeekyear; if (weekyear == -1) { nextWeekyear = 1; } else { nextWeekyear = weekyear + 1; } if (date >= fixedFromISO(nextWeekyear, 1, 1)) { weekyear = nextWeekyear; } int weekOfWeekyear = (int)(div(date - fixedFromISO(weekyear, 1, 1), 7) + 1); int dayOfWeek = (int)amod(date, 7); return new int[]{weekyear, weekOfWeekyear, dayOfWeek}; } }